#include "engine.h"
#include "vertexbuffer.h"
#include "vertexdeclaration.h"
#include "rendersystem.h"
#include <gl/glew.h>

vertexbuffer_t::vertexbuffer_t()
{
	hwid=0xffffffff;
	vdeclid=0;
	vertexnum=0;
	dynamic_offset=0;
}

/*
vertexbuffer_t::vertexbuffer_t(uint32 _vertexnum,vertexdeclaration_t* _vd)
{
	init(_vertexnum,_vd);
}
*/

void vertexbuffer_t::init(uint32 _vertexnum,vertexdeclaration_t* _vd)
{
	release();
	vertexnum=_vertexnum;
	ASSERT(vertexnum>0);

	glGenBuffers(1,&hwid);
//	ASSERT(hwid!=5);
	glBindBuffer(GL_ARRAY_BUFFER,hwid);
	glBufferData(GL_ARRAY_BUFFER,vertexnum*_vd->vertexsize,NULL,GL_STATIC_DRAW);
	vdeclid=_vd->generate_hwid();
	vertexsize=_vd->vertexsize;
}

void vertexbuffer_t::init_dynamic(vertexdeclaration_t* _vd)
{
	hwid=0;
	dynamic_offset=0;
	vdeclptr=_vd;
}

void* vertexbuffer_t::lock()
{
	ASSERT(hwid);
	glBindBuffer(GL_ARRAY_BUFFER,hwid);
	return glMapBuffer(GL_ARRAY_BUFFER,GL_WRITE_ONLY);
}

void* vertexbuffer_t::lock_read()
{
	ASSERT(hwid);
	glBindBuffer(GL_ARRAY_BUFFER,hwid);
	return glMapBuffer(GL_ARRAY_BUFFER,GL_READ_ONLY);
}

void* vertexbuffer_t::lock(uint32 _vertexnum)
{
	return RSYS->lock_dynamic_vb(_vertexnum*vdeclptr->vertexsize,dynamic_offset);
}

void vertexbuffer_t::unlock()
{
	if (hwid)
	{
		glBindBuffer(GL_ARRAY_BUFFER,hwid);
		glUnmapBuffer(GL_ARRAY_BUFFER);
	}
	else
	{
		RSYS->unlock_dynamic_vb();
	}
}

void vertexbuffer_t::release()
{
	if (hwid==0xffffffff || hwid==0) //empty vagy dynamic
		return;

	glDeleteBuffers(1,&hwid);
	hwid=0xffffffff;
//	glDeleteBuffers(1,&vdeclid);
	glDeleteVertexArrays(1,&vdeclid);
}


vertexbuffer_t::~vertexbuffer_t()
{
	release();
}

void vertexbuffer_t::set()
{
	ASSERT(hwid!=0xffffffff);
	if (hwid)
	{
		glBindBuffer(GL_ARRAY_BUFFER,hwid);
		glBindVertexArray(vdeclid);
	}
	else
	{
		GLASSERT;
		glBindBuffer(GL_ARRAY_BUFFER,RSYS->dynamic_vb_id);
		GLASSERT;
		glBindVertexArray(0);
		vdeclptr->set(dynamic_offset);
	}
}


